/*
 * SolverInformation.hpp
 *
 * Copyright 2012 Fabian Wenzelmann
 *
 * This file is part of Recognition-Procedures-for-Boolean-Functions.
 *
 * Recognition-Procedures-for-Boolean-Functions is free software: you
 * can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation,
 * either version 3 of the License, or (at your option) any later version.
 *
 * Recognition-Procedures-for-Boolean-Functions is distributed in the hope
 * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 * Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Recognition-Procedures-for-Boolean-Functions.
 *
 * If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef SOLVERINFORMATION_HPP_
#define SOLVERINFORMATION_HPP_

#include <string>
#include <utility>

#include "bfr/CoefficientType.hpp"
#include "bfr/lpbCombinatorial/SplittingTreeNode.hpp"

namespace bfr {

// forward declaration
class SplittingTree;

// TODO doc me
class SolverInformation {
    public:
        SolverInformation();
        ~SolverInformation();

        void print(const SplittingTree &tree);

        void init(const SplittingTree &tree);
        lpb_coefficient_t getCoefficient(size_t column) const;
        void setCoefficient(size_t column, lpb_coefficient_t value);

        interval_t getInterval(const SplittingTreeNode &n) const;

        void setInterval(const SplittingTreeNode &n, lpb_coefficient_t s,
                         lpb_coefficient_t b);

        interval_t solveConflict(size_t column,
                                 lpb_coefficient_t max,
                                 lpb_coefficient_t min);

        lpb_coefficient_t getSumFrom(size_t column) const;
        void resetIntervalFactor(size_t column);
        std::pair<lpb_coefficient_t, lpb_coefficient_t>
            getRepairBound(size_t column) const;

        bool setLowerRepairBound(size_t column, lpb_coefficient_t val);
        bool setUpperRepairBound(size_t column, lpb_coefficient_t val);

        std::pair<lpb_coefficient_t, lpb_coefficient_t>
            getComputedBound(size_t column) const;

        void setLowerComputedBound(size_t column, lpb_coefficient_t val);
        void setUpperComputedBound(size_t column, lpb_coefficient_t val);

        std::pair<SplittingTreeNode *, SplittingTreeNode *> getCulprit(size_t column) const;

        void setMinCulprit(size_t column, SplittingTreeNode *minCulprit);
        void setMaxCulprit(size_t column, SplittingTreeNode *maxCulprit);
 
        void setRepairFlag(size_t flag);//JGS
        size_t getRepairFlag();//JGS


    private:
        lpb_coefficient_t *coefficients;
        int *intervalFactors;
        interval_t **intervals;
        size_t columns;
        lpb_coefficient_t *coeffSum;
        std::pair<lpb_coefficient_t, lpb_coefficient_t> *repairBounds;
        std::pair<lpb_coefficient_t, lpb_coefficient_t> *computedBounds;
        int *repairFactors;
        std::pair<SplittingTreeNode *, SplittingTreeNode *> *culprits;
        size_t repairFlag;//JGS

        void destroy();
};

}

#endif  // SOLVERINFORMATION_HPP_
